﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Net.Mail;
using System.Data;

namespace BigData.Framework
{
    public class MailHelper
    {
        #region 构造函数
        static MailHelper()
        {
            DataSet ds = new DataSet();
            ds.ReadXml("BigData.Server.Message.config");

            _msgDict = new Dictionary<string, string>();
            foreach (DataRow row in ds.Tables["message"].Rows)
            {
                _msgDict[row["id"].ToString().Trim()] = row["title"].ToString().Trim();
            }
        }

        private MailHelper() { }
        #endregion

        #region 私有字段
        /// <summary>
        /// 邮件实体类
        /// </summary>
        private static MailModel _mail;

        /// <summary>
        /// Message配置字典
        /// </summary>
        private static Dictionary<string, string> _msgDict;
        #endregion

        #region 私有方法

        /// <summary>
        /// 从 config 文件初始化邮件实体类对象
        /// </summary>
        private static void InitiateMail()
        {
            if (_mail != null) return;
            _mail = new MailModel();
            DataSet ds = new DataSet();
            ds.ReadXml("BigData.Server.Message.config");
            DataRow row = ds.Tables["mail"].Rows[0];
            _mail.From = new MailAddress(row["from"].ToString().Trim()
                ,row["displayname"]==null?"":row["displayname"].ToString(),Encoding.UTF8);
            _mail.To = row["to"] == null ? "" : row["to"].ToString();
            _mail.BCC = row["bcc"] == null ? "" : row["bcc"].ToString();
            _mail.CC = row["cc"] == null ? "" : row["cc"].ToString();
            _mail.Subject  = row["subject"].ToString();
            _mail.IsBodyHtml = row["isbodyhtml"].ToString().Trim() == "1" ? true : false;
            _mail.Port = row["port"] == null ? 25 : int.Parse(row["port"].ToString().Trim());
            _mail.UserName = row["username"].ToString().Trim();
            _mail.Password = row["password"].ToString().Trim();
            _mail.Host     = row["host"].ToString().Trim();
            _mail.Endoing  = row["encoding"] == null ? Encoding.UTF8 : Encoding.GetEncoding(row["encoding"].ToString().Trim());
        }

        /// <summary>
        /// 设置地址
        /// </summary>
        /// <param name="addressTypeStr">地址 jyjzxyz@163.com;276052885@qq.com</param>
        /// <param name="collection">地址集合</param>
        private static void SetMailAddress(string addressTypeStr,MailAddressCollection collection)
        {
            if (string.IsNullOrEmpty(addressTypeStr)) return;
            string[] to = addressTypeStr.ToString().Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var t in to)
            {
                collection.Add(new MailAddress(t));
            }
        }

        /// <summary>
        /// 设置 SMTPClient
        /// </summary>
        /// <param name="msgId">邮件编号</param>
        /// <param name="msgContent">邮件内容</param>
        /// <param name="mailMsg">邮件信息对象</param>
        /// <param name="smtp">SmtpClient</param>
        private static void SetMailInfo(string msgId,
            string msgContent,
            out MailMessage mailMsg,
            out SmtpClient smtp)
        {
            InitiateMail();

            mailMsg = new MailMessage();
            mailMsg.Subject = _mail.Subject;

            mailMsg.Body = _msgDict[msgId] + "<br />" + msgContent;
            mailMsg.BodyEncoding = _mail.Endoing;
            mailMsg.IsBodyHtml = _mail.IsBodyHtml;
            mailMsg.From = _mail.From;
            SetMailAddress(_mail.To, mailMsg.To);
            SetMailAddress(_mail.BCC, mailMsg.Bcc);
            SetMailAddress(_mail.CC, mailMsg.CC);

            smtp = new SmtpClient();
            smtp.Host = _mail.Host;
            smtp.Port = _mail.Port; //默认端口是25
            smtp.UseDefaultCredentials = false;
            smtp.Credentials = new System.Net.NetworkCredential(_mail.UserName, _mail.Password);
            smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
        }
        #endregion

        #region 公有方法
        /// <summary>
        /// 同步发送邮件
        /// </summary>
        /// <param name="msgId">邮件编号</param>
        /// <param name="msgContent">邮件内容</param>
        public static void SendMail(string msgId, string msgContent)
        {
            MailMessage mailMsg;
            SmtpClient smtp;
            SetMailInfo(msgId, msgContent, out mailMsg, out smtp);
            smtp.Send(mailMsg);
        }

        /// <summary>
        /// 同步发送邮件
        /// </summary>
        /// <param name="msgId">邮件编号</param>
        /// <param name="ex">异常信息</param>
        public static void SendMail(string msgId, Exception ex)
        {
            SendMail(msgId, ex.ToString());
        }

        /// <summary>
        /// 异步发送邮件
        /// </summary>
        /// <param name="msgId">邮件编号</param>
        /// <param name="msgContent">邮件内容</param>
        public static void SendMailAsync(string msgId, string msgContent)
        {
            MailMessage mailMsg;
            SmtpClient smtp;
            SetMailInfo(msgId, msgContent, out mailMsg, out smtp);
            smtp.SendAsync(mailMsg, null);
        }

        /// <summary>
        /// 异步发送邮件
        /// </summary>
        /// <param name="msgId">邮件编号</param>
        /// <param name="ex">异常信息</param>
        public static void SendMailAsync(string msgId, Exception ex)
        {
            SendMailAsync(msgId, ex.ToString());
        }
        #endregion
    }
}
